package net.zio.kamenriderzioaddon.ridersystem.registry;

import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.zio.kamenriderzioaddon.enums.HenshinState;
import net.zio.kamenriderzioaddon.enums.SoundType;
import net.zio.kamenriderzioaddon.ridersystem.behavior.IHenshinBaseBehavior;
import net.zio.kamenriderzioaddon.ridersystem.behavior.IAwakeningHenshinBehavior;
import net.zio.kamenriderzioaddon.ridersystem.data.PlayerDataManager;
import net.zio.kamenriderzioaddon.ridersystem.util.HenshinUtils;

import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;

/**
 * 全形态配置类
 *
 * @author QianYunYi
 *
 * 全形态配置类是基础配置类的子类，用于存储全形态骑士的配置信息。
 * 它包含了基础配置类的所有属性，以及全形态特有的属性。
 */
public class FullRiderConfig extends BaseRiderConfig {

    //存储不同音效类型对应的音效事件的映射表
    private final EnumMap<SoundType, SoundEvent> soundMap = new EnumMap<>(SoundType.class);

    //基础形态变身行为处理器，用于处理变身相关逻辑
    private final IHenshinBaseBehavior henshinBaseBehavior;

     //存储强化形态配置信息的映射表，键为强化形态名称，值为对应的强化形态配置对象
    private final Map<String, AwakeningConfig> awakeningConfigs = new HashMap<>();

    /**
     * 全形态骑士配置类的构造函数
     *
     * @param riderName          骑士名称
     * @param armorSet           骑士套装盔甲数组
     * @param transformCondition 变身条件判断函数
     * @param mainHenshinItem    主手变身道具（可为空）
     * @param offhandHenshinItem  副手变身道具（可为空）
     * @param sounds             音效映射表，包含不同音效类型对应的音效事件
     * @param behavior           变身行为处理器
     */
    public FullRiderConfig(String riderName, Item[] armorSet,
                           Predicate<Player> transformCondition, Item mainHenshinItem, Item offhandHenshinItem,
                           Map<SoundType, SoundEvent> sounds, IHenshinBaseBehavior behavior) {
        // 调用父类构造函数初始化基础属性
        super(riderName, armorSet, transformCondition, mainHenshinItem, offhandHenshinItem);
        this.henshinBaseBehavior = behavior;
        // 如果传入的音效映射表不为空，则将其内容添加到当前音效映射表中
        if (sounds != null) {
            soundMap.putAll(sounds);
        }
        // 自动将当前配置注册到全局注册表中
        RiderConfigRegistry.register(this);
    }

    /**
     * 添加强化形态配置信息
     *
     * @param awakeningName      强化形态名称
     * @param awakeningArmorSet  强化形态套装物品数组
     * @param transformCondition 变身条件判断函数
     * @param mainHenshinItem    强化形态主手变身道具（可为空）
     * @param offhandHenshinItem 强化形态副手变身道具（可为空）
     * @param geizMajestySounds  强化形态音效映射表，包含不同音效类型对应的音效事件
     * @param behavior           强化形态变身行为处理器
     */
    public void addAwakeningConfig(String awakeningName,
                                   Item[] awakeningArmorSet,
                                   Predicate<Player> transformCondition,
                                   Item mainHenshinItem,
                                   Item offhandHenshinItem,
                                   Map<SoundType, SoundEvent> geizMajestySounds, IAwakeningHenshinBehavior behavior) {
        awakeningConfigs.put(awakeningName, new AwakeningConfig(
                awakeningName,
                awakeningArmorSet,
                transformCondition,
                mainHenshinItem,
                offhandHenshinItem,
                geizMajestySounds,
                behavior
        ));
    }

    /**
     * 根据强化形态名称获取对应的强化形态配置信息
     *
     * @param awakeningName 强化形态名称
     * @return 对应的强化形态配置对象，如果不存在则返回 null
     */
    public AwakeningConfig getAwakeningConfig(String awakeningName) {
        return awakeningConfigs.get(awakeningName);
    }

    /**
     * 判断是否存在指定名称的强化形态配置信息
     *
     * @param awakeningName 强化形态名称
     * @return 如果存在则返回 true，否则返回 false
     */
    public boolean hasAwakeningConfig(String awakeningName) {
        return awakeningConfigs.containsKey(awakeningName);
    }

    /**
     * 处理骑士待机状态
     *
     * @param player 进行待机状态处理的玩家对象
     */
    public void handleStandby(Player player) {
        // 调用变身行为处理器的待机处理方法
        henshinBaseBehavior.enterStandbyState(player, this);
        // 同步玩家数据
        PlayerDataManager.get(player).sync(player);
    }

    /* -------------状态操纵-------------- */
    // 获取当前状态
    public HenshinState getCurrentState(Player player) {
        return PlayerDataManager.get(player).getRiderState(this);
    }

    // 设置当前状态
    public void setCurrentState(Player player, HenshinState state) {
        PlayerDataManager.get(player).setRiderState(this, state);
    }

    /**
     * 处理骑士变身逻辑
     *
     * @param player 进行变身的玩家对象
     */
    public void handleHenshin(Player player) {
        // 调用变身行为处理器的变身处理方法
        henshinBaseBehavior.handleHenshin(player, this);
        // 同步玩家数据
        PlayerDataManager.get(player).sync(player);
    }

    /**
     * 播放指定类型的音效
     *
     * @param player 播放音效的玩家对象
     * @param type   音效类型
     */
    public void playSound(Player player, SoundType type) {
        // 如果音效映射表中包含指定类型的音效，则播放该音效
        if (soundMap.containsKey(type)) {
            HenshinUtils.playSound(player, soundMap.get(type));
        }
    }

    /**
     * 处理快速变身逻辑
     *
     * @param player 进行快速变身的玩家对象
     */
    public void handleQuickTransformation(Player player) {
        // 如果变身行为处理器不为空，则调用其快速变身处理方法
        if (henshinBaseBehavior != null) {
            henshinBaseBehavior.handleQuickTransformation(player, this);
        }
    }

    /**
     * 处理进入待机状态逻辑
     *
     * @param player 进行待机状态处理的玩家对象
     */
    public void enterStandbyState(Player player) {
        handleStandby(player);
    }

    /**
     * 处理解除变身逻辑
     *
     * @param player 进行解除变身的玩家对象
     */
    public void handleDeactivation(Player player) {
        // 如果变身行为处理器不为空，则调用其解除变身处理方法
        if (henshinBaseBehavior != null) {
            henshinBaseBehavior.handleDeactivation(player, this);
        }
    }

    /**
     * 判断是否存在强化形态配置信息
     *
     * @return 如果存在强化形态配置信息则返回 true，否则返回 false
     */
    public boolean hasAwakeningConfigs() {
        return !awakeningConfigs.isEmpty();
    }

    /**
     * 获取所有强化形态配置
     *
     * @return 强化形态配置映射表
     */
    public Map<String, AwakeningConfig> getAwakeningConfigs() {
        return awakeningConfigs;
    }


    /**
     * 获取音效映射表
     *
     * @return 存储不同音效类型对应的音效事件的映射表
     */
    @Override
    public Map<SoundType, SoundEvent> getSoundMap() {
        return soundMap;
    }


}
